package opt_generics

// comparable 所有可以比较类型集合 （允许 == 或 !=操作）
func sumIntOrFloats[K comparable, V int | float64](params map[K]V) V {
	var s V
	for _, v := range params {
		s += v
	}
	return s
}

type number interface {
	int | int32 | uint32 | int64 | uint64 | float32 | float64
}

func add[T number](a, b T) T {
	return a + b
}

func Contains[T comparable](arr []T, v T) bool {
	for _, a := range arr {
		if a == v {
			return true
		}
	}
	return false
}

func ContainsAny[T comparable](arr []T, vs ...T) bool {
	return true
}

type QNode[T any] struct {
	val  T
	next *QNode[T]
}

// 泛型传递
type Queue[Q any] struct {
	head *QNode[Q]
	end  *QNode[Q]
	len  int
}

// Queue 方法 推入元素
func (l *Queue[Q]) Push(v Q) {
	var node = &QNode[Q]{
		val:  v,
		next: nil,
	}
	// 空队判断，首位相同
	if l.head == nil {
		l.head = node
		l.end = node
	} else {
		l.end.next = node
		// current node next nil
		l.end = l.end.next
	}
	l.len++
}

func (l *Queue[Q]) Pop() *Q {
	if l.head == nil {
		return nil
	}
	v := l.head
	l.head = l.head.next
	if l.head == nil {
		l.end = nil
	}
	l.len--
	return &v.val
}
func (l *Queue[Q]) Clear() {
	l.head = nil
	l.end = nil
	l.len = 0
}

func (l *Queue[Q]) Len() int {
	return l.len
}

func (l *Queue[Q]) Head() *Q {
	if l.head == nil {
		return nil
	}
	return &l.head.val
}

func (l *Queue[Q]) End() *Q {
	if l.end == nil {
		return nil
	}
	return &l.end.val
}

func (l *Queue[Q]) Each(f func(v Q) Q) {
	p := l.head
	for p != nil {
		p.val = f(p.val)
		p = p.next
	}
}
